package com.xbongbong.crm.perform.query.detail;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmDetailTopInfoService;
import com.xbongbong.crm.service.permission.ContractPermissionServiceImpl;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.UnitEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.EsignHelp;
import com.xbongbong.paas.help.FormDataFormExplainHelper;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.CustomerUserPojo;
import com.xbongbong.paas.pojo.DataDetailPojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.HandelDetailPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.BusinessButtonService;
import com.xbongbong.paas.service.DetailTabConfigService;
import com.xbongbong.paas.service.LinkListService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.parse.data.FormDataGetAnalysisDataHelp;
import com.xbongbong.pro.appdetail.pojo.MobileDetailDirectBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailManagerBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailMoneyItemPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailScriptPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailStatusPojo;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formdata.pojo.vo.MobileFormCommonDetailVO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.process.operate.ProcessFieldHelp;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.DetailTabEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.WorkFlowEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.ShipStatusEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.ContractCompareUtil;
import com.xbongbong.util.NameUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2021/12/24 14:01
 */
@Service("contractDetailTopInfoServiceImpl")
public class ContractDetailTopInfoServiceImpl extends AbstractCrmDetailTopInfoService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ContractDetailTopInfoServiceImpl.class);

    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private FundSetModel fundSetModel;
    @Resource
    private EsignHelp esignHelp;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private LinkListService linkListService;
    @Resource
    private ContractModel contractModel;
    @Resource
    private FormDataGetAnalysisDataHelp formDataGetAnalysisDataHelp;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private ProcessFieldHelp processFieldHelp;
    @Resource
    private FormDataFormExplainHelper formDataFormExplainHelper;
    @Resource
    private PushModel pushModel;
    @Resource
    private DetailTabConfigService detailTabConfigService;
    @Resource
    private BusinessButtonService businessButtonService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private ContractPermissionServiceImpl contractPermissionService;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private ContractCompareUtil contractCompareUtil;
    @Resource
    private PackageHelp packageHelp;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.CONTRACT.getCode());
    }


    @Override
    public void checkPermission(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, UserVO loginUser, Integer businessType) throws XbbException {
        if (loginUser.isMaxDataPermission()){
            return;
        }
        //校验用户是否有查看权限
        verifyQueryPermission(businessType, loginUser, formEntity.getSaasMark(), formEntity.getMenuId(), paasFormDataEntityExt.getFlowStatus());
        //团队权限&共享权限校验
        contractPermissionService.checkPermission(formEntity, paasFormDataEntityExt, loginUser, businessType);

    }


    @Override
    public List<SummaryDataPoJo> getSummaryList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
        SummaryDataPoJo signerSummary = FormUtil.getSummaryDataPoJoByAttr(summaryList, ContractEnum.SIGN_PERSON.getAttr());
        if (Objects.nonNull(signerSummary)) {
            List<Object> values = signerSummary.getValue();
            if (Objects.nonNull(values) && !values.isEmpty()) {
                signerSummary.setValue(values);
            }
        }
        return summaryList;
    }

    @Override
    public List<SummaryDataPoJo> getLabelList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        // 解析标签
        return ExplainUtil.getSpecialSummaryList(formEntity.getLabelsList(), data, explainMap, formData);
    }

    @Override
    public List<FormTitlePoJo> getTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        return ExplainUtil.getSpecailFormTitle(JSONArray.parseArray(formEntity.getCustomTitle()), explainMap, data, list, formData);
    }

    @Override
    public List<MobileDetailMoneyItemPojo> getMobileDetailMoneyInfo(Integer distributorMark, String corpid, String userId, Integer businessType, Integer subBusinessType, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        List<MobileDetailMoneyItemPojo> moneyItemList = new ArrayList<>();
        FieldAttrEntity contractAmountFieldAttrEntity = explainMap.get(ContractEnum.AMOUNT.getAttr());
        String unit = UnitEnum.MONEY.getName();
        if (Objects.nonNull(contractAmountFieldAttrEntity) && Objects.equals(contractAmountFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object contractAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(contractAmountFieldAttrEntity, paasFormDataEntityExt.getData(),ContractEnum.AMOUNT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractAmountFieldAttrEntity.getAttrName() + "/" +unit, contractAmount, false));
        }
        FieldAttrEntity finishAmountFieldAttrEntity = explainMap.get(ContractEnum.FINISH_AMOUNT.getAttr());
        if (Objects.nonNull(finishAmountFieldAttrEntity) && Objects.equals(finishAmountFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object finishAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(finishAmountFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.FINISH_AMOUNT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(I18nMessageUtil.getMessage(I18nStringConstant.AMOUNT_COLLECTED) + unit, finishAmount, false));
        }
        FieldAttrEntity unfinishAmountFieldAttrEntity = explainMap.get(ContractEnum.UN_FINISH_AMOUNT.getAttr());
        if (Objects.nonNull(unfinishAmountFieldAttrEntity) && Objects.equals(unfinishAmountFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object unFinishAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(unfinishAmountFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.UN_FINISH_AMOUNT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(I18nMessageUtil.getMessage(I18nStringConstant.UNPAID_AMOUNT_OTHER) + unit, unFinishAmount, false));
        }
        FieldAttrEntity badAmountFieldAttrEntity = explainMap.get(ContractEnum.BAD_AMOUNT.getAttr());
        if (Objects.nonNull(badAmountFieldAttrEntity) && Objects.equals(badAmountFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object badAmount = AttrDecimalPrecisionHelper.moneyParseThrousandth(badAmountFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.BAD_AMOUNT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(I18nMessageUtil.getMessage(I18nStringConstant.AMOUNT_OF_BAD_DEBTS) + unit, badAmount, false));
        }
        FieldAttrEntity contractCostFieldAttrEntity = explainMap.get(ContractEnum.CONTRACT_COST.getAttr());
        if (Objects.nonNull(contractCostFieldAttrEntity) && Objects.equals(contractCostFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object contractCost = AttrDecimalPrecisionHelper.moneyParseThrousandth(contractCostFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.CONTRACT_COST.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractCostFieldAttrEntity.getAttrName() + "/" +unit, contractCost, false));
        }
        FieldAttrEntity contractGrossFieldAttrEntity = explainMap.get(ContractEnum.GROSS_PROFIT.getAttr());
        if (Objects.nonNull(contractGrossFieldAttrEntity) && Objects.equals(contractGrossFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object contractGrossProfit = AttrDecimalPrecisionHelper.moneyParseThrousandth(contractGrossFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.GROSS_PROFIT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractGrossFieldAttrEntity.getAttrName() + "/" +unit, contractGrossProfit, false));
        }
        FieldAttrEntity contractGrossRateFieldAttrEntity = explainMap.get(ContractEnum.GROSS_PROFIT_RATE.getAttr());
        if (Objects.nonNull(contractGrossRateFieldAttrEntity) && Objects.equals(contractGrossRateFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            String contractGrossProfitRateStr = paasFormDataEntityExt.getData().getString(ContractEnum.GROSS_PROFIT_RATE.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractGrossRateFieldAttrEntity.getAttrName() + "/%", contractGrossProfitRateStr, false));
        }
        FieldAttrEntity contractCashProfitFieldAttrEntity = explainMap.get(ContractEnum.CASH_PROFIT.getAttr());
        if (Objects.nonNull(contractCashProfitFieldAttrEntity) && Objects.equals(contractCashProfitFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            Object contractCashProfit = AttrDecimalPrecisionHelper.moneyParseThrousandth(contractCashProfitFieldAttrEntity,paasFormDataEntityExt.getData(),ContractEnum.CASH_PROFIT.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractCashProfitFieldAttrEntity.getAttrName() + "/" +unit, contractCashProfit, false));
        }
        FieldAttrEntity contractCashProfitRateFieldAttrEntity = explainMap.get(ContractEnum.CASH_PROFIT_RATE.getAttr());
        if (Objects.nonNull(contractCashProfitRateFieldAttrEntity) && Objects.equals(contractCashProfitRateFieldAttrEntity.getVisible(), BasicConstant.ONE)) {
            String contractCashProfitRateStr = paasFormDataEntityExt.getData().getString(ContractEnum.CASH_PROFIT_RATE.getAttr());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractCashProfitRateFieldAttrEntity.getAttrName() + "/%", contractCashProfitRateStr, false));
        }
        return moneyItemList;
    }

    @Override
    public JSONArray getBottomBlockInfo(String corpid, String userId, Integer businessType, PaasFormEntityExt formEntity, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt entityExt, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        JSONArray bottomBlockInfo = new JSONArray();
        List<String> userIdIn = new ArrayList<>();
        JSONObject sourceData = entityExt.getData();
        Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Long contractCustomerId = FastJsonHelper.getLongOrDefaultFromFormData(sourceData, ContractEnum.LINK_CUSTOMER.getAttr(), 0L);
        String contractCustomerName = FastJsonHelper.getStringOrDefaultFromFormData(sourceData, ContractEnum.LINK_CUSTOMER_HIDE.getAttr(), "");
        bottomBlockInfo.add(new MobileDetailDirectBlockPojo(contractCustomerId, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), contractCustomerName));

        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("contractId", dataId);
        List<ContractUserEntity> contractUserList = contractUserModel.findEntitys(param);
        contractUserList.forEach(item -> userIdIn.add(item.getUserId()));
        List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, userIdIn, true);
        userEntityList.forEach(item -> userMap.put(item.getUserId(), item));
        List<CustomerUserPojo> userPojoList = new ArrayList<>();
        contractUserList.forEach(item -> {
            UserEntity userEntity = userMap.get(item.getUserId());
            if (userEntity != null) {
                CustomerUserPojo customerUserPojo = new CustomerUserPojo();
                customerUserPojo.setUserId(userEntity.getUserId());
                customerUserPojo.setName(userEntity.getName());
                customerUserPojo.setAvatar(userEntity.getAvatar());
                customerUserPojo.setIsMain(item.getIsMain());
                userPojoList.add(customerUserPojo);
            }
        });
        bottomBlockInfo.add(new MobileDetailManagerBlockPojo(userPojoList));
        Integer editAfterFinish = processFieldHelp.isEditable(corpid, explainMap, entityExt.getAppId(), entityExt.getFormId(), entityExt.getFlowStatus(), ContractEnum.STATUS.getAttr(), handlerExplainDTO);
        bottomBlockInfo.add(getMobileDetailStatusBlockPojo(corpid, sourceData, DictionaryEnum.CONTRACT_STATUS, ContractEnum.STATUS.getAttr(), editAfterFinish));
        return bottomBlockInfo;
    }

    @Override
    public List<MobileDetailScriptPojo> getDetailShowScript(Integer businessType, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        String attr = ContractEnum.AMOUNT.getAttr();
        return setDetailShowScript(paasFormDataEntityExt, businessType, paasFormDataEntityExt.getData(), explainMap, attr);
    }

    @Override
    public MobileDetailStatusPojo getDetailShowStatus(Integer businessType, JSONObject data) throws XbbException {
        Integer isRed = getIntegerOrDefaultFromFormData(data, ContractEnum.IS_RED.getAttr(), 0);
        MobileDetailStatusPojo mobileDetailStatusPojo = new MobileDetailStatusPojo();
        if (Objects.equals(isRed, 1)) {
            // 状态为红冲
            mobileDetailStatusPojo.setName("isRed");
            mobileDetailStatusPojo.setValue(isRed);
        }
        Integer hasRed = getIntegerOrDefaultFromFormData(data, ContractEnum.HAS_RED.getAttr(), 0);
        if (Objects.equals(hasRed, 1)) {
            // 状态为已退款
            mobileDetailStatusPojo.setName("hasRed");
            mobileDetailStatusPojo.setValue(hasRed);
        }
        Integer contractArchived = getIntegerOrDefaultFromFormData(data, ContractEnum.ARCHIVED.getAttr(), 2);
        mobileDetailStatusPojo.setName("archived");
        mobileDetailStatusPojo.setValue(contractArchived);
        return mobileDetailStatusPojo;
    }

    @Override
    public Map<String, Object> getDetailShowOperation(String corpid, String userId, Integer businessType, Long dataId, JSONObject data) throws XbbException {
        Map<String, Object> param = new HashMap<>(BasicConstant.ONE);
        //有提醒的合同
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(Collections.singletonList(dataId), corpid, XbbRefTypeEnum.CONTRACT.getCode(), pushNotifyList);
        if (!pushNotifyList.isEmpty()) {
            param.put("message", true);
        }
        return param;
    }

    @Override
    public JSONObject returnSaasObject(String corpid, Integer businessType, UserVO userVO, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        JSONObject saasReturnObj = new JSONObject();
        Integer enable = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias());
        boolean openDistribution = Objects.equals(enable, BasicConstant.IS_USE);
        saasReturnObj.put(CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias(), openDistribution);
        //快捷新建跟进记录tab栏显示与否
        saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
        //动态显示与否
        saasReturnObj.put(StringConstant.DYNAMIC, true);
        //动态名称
        saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
        return saasReturnObj;
    }



    @Override
    public void returnVO(PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, MobileFormCommonDetailVO mobileFormCommonDetailVO, String userId) throws XbbException {
        mobileFormCommonDetailVO.setHasOuterLinkShare(setOuterLinkShare(formEntity.getCorpid(), formEntity.getId()));
        mobileFormCommonDetailVO.setDistributorMark(formEntity.getDistributorMark());
        mobileFormCommonDetailVO.setPaasFormEntity(formEntity);
    }

    @Override
    public List<ButtonPojo> handleDetailButton(FormDataDetailDTO formDataDetailDTO, HandelDetailPojo handelDetailPojo, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        List<ButtonPojo> buttonPojoList = handelDetailPojo.getButtonPojoList();
        JSONObject dataList = formData.getData();
        Integer businessType = handelDetailPojo.getBusinessType();
        Integer contractArchived = getIntegerOrDefaultFromFormData(dataList, ContractEnum.ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
        UserVO userVO = handelDetailPojo.getLoginUser();
        List<BusinessDetailButtonEnum> buttonEnumList = BusinessDetailButtonEnum.getByBusinessTypeAndPermission(businessType, userVO.getPermSet());
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO(userVO, formData);
        boolean perTag = commonPermissionHelp.checkEditPermissionWithoutShareEdit(formDataDetailDTO, verifyViewPermissionDTO, explainMap);
        for (BusinessDetailButtonEnum buttonEnum : buttonEnumList) {
            if (Objects.equals(contractArchived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.CONTRACT_CANCEL_ARCHIVED)) {
                continue;
            } else if (Objects.equals(contractArchived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.CONTRACT_ARCHIVED)) {
                continue;
            }
            if (Objects.equals(buttonEnum.getAnEnum().getAttr(), SaasButtonEnum.CONTRACT_COMPARE.getAttr()) && !contractCompareUtil.showCompareButton(formDataDetailDTO.getCorpid(), formDataDetailDTO.getLoginUser().getPermSet(), userVO.getUserId())) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            SaasButtonEnum saasButtonEnum = buttonEnum.getAnEnum();
            if (!perTag && Objects.equals(SaasButtonEnum.EDIT.getAttr(), saasButtonEnum.getAttr())) {
                continue;
            }
            BeanUtil.copyProperties(saasButtonEnum, buttonPojo);
            buttonPojo.setLinkBusinessType(buttonEnum.getLinkBusinessType());
            buttonPojoList.add(buttonPojo);
        }
        return buttonPojoList;
    }



    @Override
    public DetailTitlePojo handleDetailFocus(FormDataDetailDTO formDataDetailDTO,  Integer businessType, PaasFormDataEntityExt paasFormDataEntityExt, String userId) throws XbbException {
        DetailTitlePojo detailTitlePojo = new DetailTitlePojo();
        Integer isFocus = BasicConstant.NO_USE;
        detailTitlePojo.setIsFocus(isFocus);
        return detailTitlePojo;
    }

    @Override
    public List<WorkFlowPojo> webHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData) throws XbbException {
        String corpid = formEntity.getCorpid();
        JSONObject dataList = formData.getData();
        Integer isAllComing = getIntegerOrDefaultFromFormData(dataList, ContractEnum.ALL_OUT_BOUND.getAttr(), BasicConstant.ZERO);
        String isShipped = FastJsonHelper.getStringOrDefaultFromFormData(dataList, ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
        Double amount = FastJsonHelper.getDoubleOrDefaultFromFormData(dataList, ContractEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
        Double unFinishAmount = FastJsonHelper.getDoubleOrDefaultFromFormData(dataList, ContractEnum.UN_FINISH_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
        UserVO userVO = handelDetailPojo.getLoginUser();
        Set<String> permSet = userVO.getPermSet();
        Integer businessType = handelDetailPojo.getBusinessType();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermission(businessType, permSet);
        // 获取对应businessType的alias
        List<String> aliasIn = WorkFlowEnum.getAliasIn(workFlowEnumList);

        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("contractId",formData.getId());
        List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(param);
        double invoiceAmount = 0;
        if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntityList)){
            for(InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntityList) {
                invoiceAmount = Arith.add(invoiceAmount, invoiceRelationshipEntity.getMoney());
            }
        }
        List<ContractProductEntity> contractProductEntityList = contractProductModel.getContractProductByContractIdIn(corpid, 0, Collections.singletonList(formData.getId()));
        boolean notNeedPurchase = contractProductEntityList.isEmpty();
        //工单未开，以及没有可以用的工单模板，移除关联新建工单
        boolean workOrderEnable = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        List<WorkOrderFormEntity> workOrderEnableForms = workOrderFormModel.getTemplateWithPermission(corpid, userVO, null, null);
        if (!workOrderEnable || (Objects.nonNull(workOrderEnableForms) && workOrderEnableForms.isEmpty())) {
            workFlowEnumList.remove(WorkFlowEnum.CONTRACT_WORK_ORDER);
        }

        // 查询是否可以超发出库
        FormConfigEntity overOutstockConfig = formConfigModel.getEntityByFormId(corpid, formData.getFormId(), FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD.getConfig());
        boolean overOutstock = Objects.nonNull(overOutstockConfig) && Objects.equals(overOutstockConfig.getConfigValue(), "1");
        Long nowModelType = fundSetModel.getModelType(corpid,XbbRefTypeEnum.CRM);
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            if (Objects.equals(isAllComing, BasicConstant.ONE) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_OUTSTOCK) && !overOutstock) {
                continue;
            }
            if ((Objects.equals(isShipped, ShipStatusEnum.CLOSED.getCode())&& Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_OUTSTOCK))) {
                continue;
            }

            if (esignHelp.addEsignWorkFlow(permSet, workFlowPojoList, workFlowEnum,
                    xbbRefTypeEnum, formData)) {
                continue;
            }

            if (invoiceAmount >= amount && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_INVOICE)) {
                continue;
            }
            if (notNeedPurchase && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PURCHASE)) {
                continue;
            }
            if (unFinishAmount <= BasicConstant.ZERO_DOUBLE && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PAYMENT)) {
                continue;
            }
            if (!Objects.equals(nowModelType, ModelTypeEnum.PLAN.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PAYMENT)) {
                continue;
            }
            WorkFlowPojo workFlowPojo = new WorkFlowPojo();
            BeanUtil.copyProperties(workFlowEnum, workFlowPojo);
            NameUtil.changeValue(paasBusinessTypeToName, workFlowPojo);
            workFlowPojo.setDistributorMark(DistributorMarkEnum.OTHER.getCode());
            workFlowPojoList.add(workFlowPojo);
        }
        // 关联新建
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        workFlowPojoList.addAll(linkListService.getCommonButton(linkList, formData.getDel(), handelDetailPojo.getLoginUser(), formData.getAppId(), formData.getFormId(), handelDetailPojo.getBusinessType(), SaasMarkEnum.SAAS.getCode(), corpid));
        return workFlowPojoList;
    }


    @Override
    public List<TopPermissionsPoJo> dingtalkHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        String corpid = formEntity.getCorpid();
        UserVO userVO = handelDetailPojo.getLoginUser();
        Integer businessType = formEntity.getBusinessType();
        JSONObject dataList = formData.getData();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermissionForDingtalk(businessType, userVO.getPermSet());
        Double amount = getDoubleOrDefaultFromFormData(dataList, ContractEnum.AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
        Double unFinishAmount = getDoubleOrDefaultFromFormData(dataList, ContractEnum.UN_FINISH_AMOUNT.getAttr(), BasicConstant.ZERO_DOUBLE);
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del",BasicConstant.ZERO);
        param.put("contractId",formData.getId());
        Double invoiceAmount = 0D;
        List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(param);
        if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntityList)){
            for(InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntityList) {
                invoiceAmount = Arith.add(invoiceAmount, invoiceRelationshipEntity.getMoney());
            }
        }
        List<String> aliasIn = new ArrayList<>();
        workFlowEnumList.forEach(item -> aliasIn.add(XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias()));
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);

        Integer isContractArchived = getIntegerOrDefaultFromFormData(dataList, ContractEnum.ARCHIVED.getAttr(),ArchivedEnum.UN_ARCHIVED.getCode());
        List<ContractProductEntity> contractProductEntityList = contractProductModel.getContractProductByContractIdIn(corpid, 0, Collections.singletonList(formData.getId()));
        boolean notNeedPurchase = contractProductEntityList.isEmpty();
        Integer isAllComing = getIntegerOrDefaultFromFormData(dataList, ContractEnum.ALL_OUT_BOUND.getAttr(), BasicConstant.ZERO);
        String shipstatus = FastJsonHelper.getStringOrDefaultFromFormData(dataList, ContractEnum.SHIP_STATUS.getAttr(), ShipStatusEnum.UNSHIPPED.getCode());
        Set<String> loginUserPermSet = userVO.getPermSet();
        PaasMenuEntity prepayMenu = paasMenuModel.getByAlias(XbbRefTypeEnum.PREPAYMENT_BALANCE.getAlias(), corpid);
        //true预付款开启
        boolean prePayFlag = prepayMenu != null && Objects.equals(prepayMenu.getEnable(), BasicConstant.ONE);

        List<TopPermissionsPoJo> topPermissions = businessButtonService.dingtalkDetailCommon(userVO, formEntity, explainMap, formData);
        Long nowModelType = fundSetModel.getModelType(corpid,XbbRefTypeEnum.CRM);
        // 查询是否可以超发出库
        FormConfigEntity overOutstockConfig = formConfigModel.getEntityByFormId(corpid, formData.getFormId(), FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD.getConfig());
        boolean overOutstock = Objects.nonNull(overOutstockConfig) && Objects.equals(overOutstockConfig.getConfigValue(), "1");
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
            if (esignHelp.addEsignWorkFlow(loginUserPermSet, workFlowPojoList, workFlowEnum,
                    XbbRefTypeEnum.CONTRACT, formData)) {
                if (workFlowPojoList.isEmpty()) {
                    continue;
                }
            }

//            if (!hasUpdate && (Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_ARCHIVED) || Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_CANCEL_ARCHIVED))) {
//                continue;
//            }
            if (Objects.equals(isContractArchived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_ARCHIVED)) {
                continue;
            }
            if (Objects.equals(isContractArchived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_CANCEL_ARCHIVED)) {
                continue;
            }
            if (notNeedPurchase && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PURCHASE)) {
                continue;
            }
            if (Objects.equals(isAllComing, BasicConstant.ONE) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_OUTSTOCK) && !overOutstock) {
                continue;
            }
            if (Objects.equals(shipstatus, ShipStatusEnum.CLOSED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_OUTSTOCK)) {
                continue;
            }
            if (invoiceAmount >= amount && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_INVOICE)) {
                continue;
            }
            if ( Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_WRITE_OFF_PREPAYMENT) && !prePayFlag) {
                continue;
            }
            if ( unFinishAmount <= 0D && (Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_WRITE_OFF_PREPAYMENT) || Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PAYMENT_SHEET) || Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PAYMENT_SHEET_BAD) )) {
                continue;
            }
            if (!Objects.equals(nowModelType, ModelTypeEnum.PLAN.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CONTRACT_PAYMENT)) {
                continue;
            }
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            BeanUtil.copyProperties(workFlowEnum, topPermissionsPoJo);
            if (Objects.equals(workFlowEnum.getFormRelation(), BasicConstant.ONE)) {
                NameUtil.changeValue(paasBusinessTypeToName, topPermissionsPoJo);
            }
            topPermissions.add(topPermissionsPoJo);
        }
        List<LinkListPojo> linkList = formEntity.getLinkListList();
        topPermissions.addAll( linkListService.getDingtalkCommonButton(linkList, formData.getDel(), userVO, formData.getAppId(), formData.getFormId(), businessType, formEntity.getSaasMark(), corpid));
        return topPermissions;
    }

    @Override
    public DataDetailPojo handleDetailData(Integer businessType, PaasFormDataEntityExt formData, String userId, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        DataDetailPojo dataDetailPojo = new DataDetailPojo();
        // 外链
        Integer outerLinkShare = setOuterLinkShare(handlerExplainDTO.getCorpid(), formData.getFormId());
        dataDetailPojo.setHasOuterLinkShare(outerLinkShare);
        return dataDetailPojo;
    }



    @Override
    public JSONArray getSecondTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<SummaryDataPoJo> summaryList = getSummaryList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        return getSecondTitleList(summaryList, data, formDataDetailDTO.getCorpid(), formEntity.getId());
    }

    @Override
    public JSONArray getTagList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Integer businessType = formEntity.getBusinessType();
        Long dataId = formData.getId();
        String userId = formDataDetailDTO.getUserId();
        List<SummaryDataPoJo> labelsList = getLabelList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        JSONArray tags = new JSONArray();
        //是否包含红冲合同（即是否为退货合同）
        Integer hasRed = data.getIntValue(ContractEnum.HAS_RED.getAttr());
        if (Objects.equals(hasRed, 1)) {
            JSONObject object = new JSONObject();
            object.put("type", "red");
            object.put("value", I18nMessageUtil.getMessage(I18nStringConstant.RETURN_CONTRACT));
            tags.add(object);
        }
        tags.addAll(getTags(labelsList, corpid, businessType, dataId, userId));
        return tags;
    }

    @Override
    public String getTitle(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<FormTitlePoJo> formTitleList = getTitleList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        return TitleUtil.getWebTitle(formTitleList);
    }

    @Override
    public List<DetailTabPojo> handleDetailTab(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap, HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        String corpid = formEntity.getCorpid();
        Integer businessType = handelDetailPojo.getBusinessType();
        // 获取web和dingtalk的tab
        List<BusinessDetailTabEnum> tabEnumList = BusinessDetailTabEnum.getTabByBusinessTypeAndPermission(businessType, userVO.getPermSet(), handlerExplainDTO.getPlatform());

        // 获取对应businessType的alias
        List<String> aliasIn = BusinessDetailTabEnum.getAliasIn(tabEnumList);

        // 记录businessType与menuName的关系
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        Integer enable = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias());
        boolean openDistribution = Objects.equals(enable, BasicConstant.IS_USE);
        // 判断关联产品字段是否可见
//        boolean contractProduct = commonHelp.attrCanSee(ContractEnum.PRODUCT.getAttr(), explainMap, handlerExplainDTO);
        // 判断是否开启过进销存
        Boolean isJxcUse = false;
        PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(),corpid);
        if (Objects.nonNull(paasAppEntity)) {
            isJxcUse = true;
        }
        //判断当前阶段推进器字段可见权限，以及是否启用
        boolean ifContractStageOpen = false;
        for (String attr : explainMap.keySet()) {
            FieldAttrEntity fieldAttr = explainMap.get(attr);
            if (Objects.equals(fieldAttr.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType()) && Objects.equals(fieldAttr.getIsOpen(), 1)) {
                ifContractStageOpen = !ExplainUtil.isFieldNeedHide(fieldAttr, handlerExplainDTO);
                break;
            }
        }
        List<DetailTabPojo> tabPojoList = new ArrayList<>();
        for (BusinessDetailTabEnum tabEnum : tabEnumList) {
            // 移动端不需要阶段历史
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_STAGE) && Objects.equals(handlerExplainDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                continue;
            }
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_STAGE) && !ifContractStageOpen) {
                continue;
            }
            if (!openDistribution && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_PERFORMANCE)) {
                continue;
            }
                   /* if (!contractProduct && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_PRODUCT_LIST)) {
                        continue;
                    }*/
            Integer hasRed = getIntegerOrDefaultFromFormData(formData.getData(), ContractEnum.HAS_RED.getAttr(), BasicConstant.ZERO);
            if (!Objects.equals(hasRed, BasicConstant.ONE) && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_REFUND)) {
                continue;
            }
            if ( !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_VIEW.getAlias()) && !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_VIEW.getAlias()) && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_PAYMENT) ) {
                continue;
            }
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_RELEVANCE_PURCHASE) && !isJxcUse){
                continue;
            }
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(tabEnum.getAnEnum(), detailTabPojo);
            NameUtil.changeTabEnumName(paasBusinessTypeToName, tabEnum, detailTabPojo);
            detailTabPojo.setAttr(detailTabPojo.getKey());
            //判断是否有回款单，是否有应收款、回款计划权限
            if ( Objects.equals(tabEnum, BusinessDetailTabEnum.CONTRACT_PAYMENT) ) {
                Boolean isHasPayment = false;
                Boolean isHasPaymentSheet = false;
                if ( userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_VIEW.getAlias()) ) {
                    isHasPaymentSheet = true;
                }
                if ( userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_VIEW.getAlias()) ) {
                    isHasPayment = true;
                }
                detailTabPojo.setIsHasPayment(isHasPayment);
                detailTabPojo.setIsHasPaymentSheet(isHasPaymentSheet);
            }
            if (Objects.equals(tabEnum.getAnEnum().getKey(), DetailTabEnum.CONTRACT_COMPARE.getKey()) && !contractCompareUtil.showCompareTab(corpid, handelDetailPojo.getLoginUser().getPermSet(), userVO.getUserId())) {
                continue;
            }
            tabPojoList.add(detailTabPojo);
        }
        handleTeamTab(tabPojoList, explainMap);
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        handlerExplainVO.setAppId(formEntity.getAppId());
        handlerExplainVO.setFormId(formEntity.getId());
        // 公共tab
        tabPojoList.addAll(linkListService.commonTab(corpid, userVO, handlerExplainVO, handlerExplainDTO, businessType, formData.getDel(), linkList));
        // tab排序
        tabPojoList = detailTabConfigService.handleDetailTabSort(userVO.getUserId(), corpid, handlerExplainVO.getFormId(), businessType, tabPojoList);
        return tabPojoList;
    }


    @Override
    public JSONObject analysisData(PaasFormDataEntityExt paasFormDataEntityExt, HandlerExplainDTO handlerExplainDTO, HandlerExplainVO handlerExplainVO) throws XbbException {
        Long formId = paasFormDataEntityExt.getFormId();
        List<FieldAttrEntity> list = handlerExplainVO.getHeadList();
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(list.size());
        list.forEach(item->explainMap.put(item.getAttr(), item));

        ParseSingleRowDataVO parseSingleRowDataVO = commonAnalysisData(paasFormDataEntityExt, handlerExplainDTO, handlerExplainVO, list, explainMap);
        JSONObject data = parseSingleRowDataVO.getResult();
        SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
        BeanUtil.copyProperties(handlerExplainDTO, saasAnalysisDataDTO);
        saasAnalysisDataDTO.setFormId(formId);
        contractModel.formatData(saasAnalysisDataDTO, data);
        //处理千分位
        FormDataGetVO formDataGetVO = new FormDataGetVO();
        formDataGetVO.setData(data);
        formDataGetAnalysisDataHelp.analysisGetOfThousandBits(formDataGetVO, list, false);
        return data;
    }
}
